package com.bt.lms.ui.page.sys.user.action;

import com.bt.lms.constants.BOConstant;
import com.bt.lms.constants.SysBizTypeConstant;
import com.bt.lms.entity.User;
import com.bt.lms.network.msg.RespMsg;
import com.bt.lms.ui.page.sys.utils.*;
import com.bt.lms.ui.page.sys.ServerInfo;
import com.bt.lms.network.msg.ReqMsg;
import com.bt.lms.ui.page.sys.vo.UserTableViewVo;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.List;


/**
 * 重置密码按钮事件（用户列表界面）
 *
 * @author 徐大永
 */
public class ULResetPwdBtnAction implements EventHandler<ActionEvent> {

    /**
     * 用户信息
     */
    private final UserTableViewVo userTableViewVo;

    /**
     * 构建重置密码事件
     * @param userTableViewVo 用户信息
     */
    public ULResetPwdBtnAction(UserTableViewVo userTableViewVo) {
        this.userTableViewVo = userTableViewVo;
    }

    /**
     * 弹窗提示，要求更改界面
     *
     * @param event the event which occurred
     */
    @Override
    public void handle(ActionEvent event) {

        Alert alert = new Alert(Alert.AlertType.NONE);
        alert.setHeaderText(null);//自带提示
        PageUserResetPwd pageUserResetPwd = new PageUserResetPwd(alert,userTableViewVo);
        alert.setGraphic(pageUserResetPwd); //内容显示
        alert.getDialogPane().setMaxWidth(500);//宽度
        alert.getDialogPane().setMaxHeight(500);////高度
        alert.showAndWait();//展示并等待

    }

}

/**
 * 重设密码界面
 *
 * @author 徐大永
 */
class PageUserResetPwd extends VBox {

    /**
     * 确认新密码文本框id
     */
    public static final String NOTARIZE_PWD_TF_ID = "notarizePwd";
    /**
     * 新密码文本框id
     */
    public static String PWD_TF_ID = "password";

    /**
     * 界面弹窗
     */
    private final Alert alert;

    /**
     * 用户信息
     */
    private final UserTableViewVo userTableViewVo;

    /**
     * 构建界面
     * @param alert 界面弹窗
     * @param userTableViewVo 用户信息
     */
    public PageUserResetPwd(Alert alert, UserTableViewVo userTableViewVo) {

        //维护
        this.alert = alert;
        this.userTableViewVo = userTableViewVo;

        //布局
        this.setSpacing(10);
        this.setAlignment(Pos.CENTER_RIGHT);
        this.setPadding(new Insets(50));

        //组件
        HBox hBox = new HBox();
        this.getChildren().add(hBox);
        hBox.setSpacing(10);
        Label label = new Label("新密码：");
        label.setPrefWidth(150);
        label.setAlignment(Pos.CENTER_RIGHT);
        TextField newPwd = new TextField();
        newPwd.setId(PWD_TF_ID);
        hBox.getChildren().addAll(label, newPwd);

        HBox hBox1 = new HBox();
        hBox1.setSpacing(10);
        this.getChildren().add(hBox1);
        Label label1 = new Label("确认新密码：");
        label1.setPrefWidth(150);
        label1.setAlignment(Pos.CENTER_RIGHT);
        TextField formerPwdTF = new TextField();
        formerPwdTF.setId(NOTARIZE_PWD_TF_ID);
        hBox1.getChildren().addAll(label1, formerPwdTF);

        MyHBox operateHBox = new MyHBox();
        operateHBoxInit(operateHBox);
        this.getChildren().add(operateHBox);

    }

    /**
     * 操作盒子初始化
     *
     * @param operateHBox 操作盒子
     */
    private void operateHBoxInit(MyHBox operateHBox) {

        //布局
        operateHBox.setSpacing(10);
        operateHBox.setAlignment(Pos.CENTER);

        Button save = new Button("保存");
        operateHBox.getChildren().add(save);
        //事件
        UserResetPwdSaveBtnAction userResetPwdSaveBtnAction = new UserResetPwdSaveBtnAction(alert, this, userTableViewVo);
        save.setOnAction(userResetPwdSaveBtnAction);

        MyButton cancel = new MyButton("取消");
        operateHBox.getChildren().add(cancel);
        //事件
        cancel.setOnAction(event -> {
            ButtonType buttonType = new ButtonType("");
            alert.getDialogPane().getButtonTypes().add(buttonType);//添加按钮样式
            alert.close();
        });
    }
}

/**
 * 用户重设密码界面保存按钮事件
 */
class UserResetPwdSaveBtnAction implements EventHandler<ActionEvent> {

    /**
     * 重设密码界面
     */
    private final PageUserResetPwd pageUserResetPwd;

    /**
     * 弹窗
     */
    private final Alert alert;

    /**
     * 用户信息
     */
    private final UserTableViewVo userTableViewVo;

    /**
     * 构建事件
     *
     * @param alert 界面弹窗
     * @param pageUserResetPwd 重设密码界面
     * @param userTableViewVo 用户信息
     */
    public UserResetPwdSaveBtnAction(Alert alert, PageUserResetPwd pageUserResetPwd, UserTableViewVo userTableViewVo) {
        this.alert = alert;
        this.pageUserResetPwd = pageUserResetPwd;
        this.userTableViewVo = userTableViewVo;
    }

    @Override
    public void handle(ActionEvent event) {
        //莫名其妙关闭了
        ButtonType buttonType = new ButtonType("");
        alert.getDialogPane().getButtonTypes().add(buttonType);//添加按钮样式
        alert.close();//只有存在按钮样式，才可以关闭

        //1.获取用户输入
        ResetPwdInfo resetPwdInfo = getInput();
        //2.验证用户输入
        String hint = verifyInput(resetPwdInfo);
        User user = new User();
        user.setId(userTableViewVo.getId());
        user.setPassword(resetPwdInfo.getPassword());
        //3.组装消息包
        if (hint == null) {
            //验证通过
            ReqMsg reqMsg = Encode.encodeToMsg(user, SysBizTypeConstant.USER_RESET_PWD);
            byte[] sumBytes = reqMsg.toBytes();
            try {
                //4.组网
                Socket socket = packageNet();
                OutputStream out = socket.getOutputStream();
                //5.发
                boolean result = sendMes(out, sumBytes);
                if (result) {
                    InputStream in = socket.getInputStream();
                    //2.1 接收
                    List<byte[]> receive = NetWorkUtils.receive(in);
                    //2.2 整理读到的字节流
                    byte[] respBytes = ArrayUtils.joinBytes(receive);
                    //2.2 字节流转响应消息
                    RespMsg respMsg = RespMsg.toRespMsg(respBytes);
                    //2.3 判断状态
                    short status = respMsg.getStatus();
                    if (status == RespMsg.NETWORK_STATUS_NORMAL) {
                        //2.4 关流，结束
                        in.close();
                        out.close();
                        socket.close();
                        hintFrame(null);
                    }

                } else {
                    //发送失败
                    String hintStr = "发送网络失败，请稍候重试";
                    hintFrame(hintStr);
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } else {
            //提示框
            hintFrame(hint);
        }

    }


    /**
     * 提示框
     *
     * @param hint 提示文本
     */
    private void hintFrame(String hint) {

        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        if (hint == null) {
            //正常结束
            alert.setTitle("保存");
            alert.setHeaderText(null);
            alert.setContentText("修改密码成功。");
            alert.showAndWait();

        } else {
            //弹窗提示
            alert.setTitle("失败");
            alert.setHeaderText(null);
            alert.setContentText(hint);
            alert.showAndWait();
        }

    }

    /**
     * 发网
     *
     * @param out 输出流
     * @param bytes  要发送的数据
     * @return 发送结果
     */
    private boolean sendMes(OutputStream out, byte[] bytes) {

        //发送
        try {
            out.write(bytes);
            out.flush();
            return true;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 组网
     *
     * @return 网
     */
    private Socket packageNet() {

        String ip = ServerInfo.IP;
        Integer port = ServerInfo.PORT;

        try {
            return new Socket(ip, port);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 验证用户输入
     *
     * @param resetPwdInfo 用户输入
     * @return 验证结果
     */
    private String verifyInput(ResetPwdInfo resetPwdInfo) {

        String text = "";

        String newPwd = resetPwdInfo.getPassword();
        String formerPwd = resetPwdInfo.getNotarizePwd();

        if (!newPwd.equals(formerPwd)) {
            text += "两次密码输入不一致。";
        }


        if ("".equals(text))
            return null;
        else
            return text;
    }

    /**
     * 获取用户输入
     *
     * @return 编辑用户信息VO
     */
    private ResetPwdInfo getInput() {

        //要返回的对象
        ResetPwdInfo resetPwdInfo = new ResetPwdInfo();

        //notarizePwd
        TextField formerPwdTF = (TextField) pageUserResetPwd.lookup("#"+PageUserResetPwd.NOTARIZE_PWD_TF_ID);
        String formerPwd = formerPwdTF.getText();
        resetPwdInfo.setNotarizePwd(formerPwd);

        TextField newPwdTF = (TextField) pageUserResetPwd.lookup("#"+PageUserResetPwd.PWD_TF_ID);
        String newPwd = newPwdTF.getText();
        resetPwdInfo.setPassword(newPwd);

        return resetPwdInfo;
    }
}

/**
 * 密码重设信息
 */
class ResetPwdInfo {

    /**
     * 确认新密码
     */
    private String notarizePwd;

    /**
     * 新密码
     */
    private String password;

    public String getNotarizePwd() {
        return notarizePwd;
    }

    public void setNotarizePwd(String notarizePwd) {
        this.notarizePwd = notarizePwd;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
